package com.util;

import java.awt.Rectangle;

import java.io.File;
import java.io.IOException;

import java.net.URL;

import java.util.HashMap;
import java.util.Iterator;
import java.util.Map;

import javax.imageio.ImageIO;
import javax.imageio.ImageReader;
import javax.imageio.stream.ImageInputStream;

import org.apache.commons.io.FileUtils;

import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;

import com.conf.CommonConfig;


import magick.CompressionType;
import magick.ImageInfo;
import magick.MagickException;
import magick.MagickImage;
import magick.PreviewType;



public class ImageUtil {
	static {
		System.setProperty("jmagick.systemclassloader", "no");
	}
	private final static Log log = (Log) LogFactory.getLog(ImageUtil.class);
	private int width = 1;
	private int height = 1;
	private ImageInfo info;
	public final static byte IMG_SQUARE = 0;
	public final static byte IMG_OBLONG = 1;
    private final static String USER="fantong";
	private final static String PASSWORD="fantong@cc"; 
	public ImageUtil(int width, int height, String source) {
		try {
			log.info(source);
			info = new ImageInfo(source);
			info.setCompression(CompressionType.JPEGCompression);
			info.setPreviewType(PreviewType.JPEGPreview);
			this.width = width;
			this.height = height;
		}
		catch (Exception e) {
			log.error(e.toString());
			e.printStackTrace();
		}
	}

	/*****
	 * 按照尺寸切图
	 * 
	 * @param newFileName
	 * @param w
	 * @param h
	 */
	public void makePic(String newFileName, int w, int h) {
		try {
			System.out.println("-------------------make start-------------------");
			info.setQuality(90);
			MagickImage image = new MagickImage(info);
			image.profileImage("*", null);
			MagickImage scaled = null;

			if (width < w && height < h) {
				scaled = image.scaleImage(width, height);
			} else {
				if (width < w && height > h)
					scaled = image.scaleImage(width, h);
				else if (width > w && height < h)
					scaled = image.scaleImage(w, height);
				else
					scaled = image.scaleImage(w, h);
			}

			scaled = scaled.sharpenImage(1.0, 5.0);
			scaled.setFileName(newFileName);
			scaled.writeImage(info);

			System.out.println("-------------------over-------------------");
		} catch (MagickException e) {
			log.error(e.toString());
			e.printStackTrace();
		}
	}
	
	
	
	
	
	public void makeSmall(String newFileName, int size) {
		try {
			info.setQuality(90);
			MagickImage image = new MagickImage(info);
			image.profileImage("*", null);
			MagickImage scaled = null;
			double proportion = 0;
			if (width < size && height < size) {
				scaled = image.scaleImage(width, height);
			} else {
				if (width == height) {
					scaled = image.scaleImage(size, size);
				} else {
					if (width > height) {
						if (width > size) {
							proportion = (double) size / width;
						} else {
							proportion = width / (double) size;
						}
						scaled = image.scaleImage(size, (int) (height * proportion));
					} else {
						if (height > size) {
							proportion = (double) size / height;
						} else {
							proportion = height / (double) size;
						}
						scaled = image.scaleImage((int) (width * proportion), size);
					}
				}
			}
			scaled = scaled.sharpenImage(1.0, 5.0);
			scaled.setFileName(newFileName);
			scaled.writeImage(info);
		} catch (MagickException e) {
			log.error(e.toString());
			e.printStackTrace();
		}
	}
	
	public void makeBig(String newFileName, int size) {
		try {
			info.setQuality(90);
			MagickImage image = new MagickImage(info);
			image.profileImage("*", null);
			MagickImage scaled = null;
			double proportion = 0;
			if (width == height) {
				if (width > size) {
					proportion = (double) size / width;
					scaled = image.scaleImage((int) (width * proportion), (int) (width * proportion));
				} else {
					scaled = image.scaleImage(width, height);
				}
			} else {
				if (width > height) {
					if (width > size) {
						proportion = (double) size / width;
						scaled = image.scaleImage(size, (int) (height * proportion));
					} else {
						scaled = image.scaleImage(width, height);
					}
				} else {
					if (height > size) {
						proportion = (double) size / height;
						scaled = image.scaleImage((int) (width * proportion), size);
					} else {
						scaled = image.scaleImage(width, height);
					}
				}
			}
			if (size > 800) {
				scaled = scaled.sharpenImage(1.0, 1.0);
			} else {
				scaled = scaled.sharpenImage(1.0, 5.0);
			}
			scaled.setFileName(newFileName);
			scaled.writeImage(info);
		} catch (MagickException e) {
			log.error(e.toString());
			e.printStackTrace();
		}
	}


	public void makeSquare(String newFileName, int size) throws Exception {
		Rectangle rect = null;
		if (width < size && height < size) {
			rect = new Rectangle(0, 0, size, size);
		}
		else if (width < size || height < size) {
			rect = new Rectangle(0, 0, size, size);
		}
		else {
			if (width < height) {
				int beginPoint = (height - width) / 2;
				rect = new Rectangle(0, beginPoint, width, width);
			}
			else {
				int beginPoint = (width - height) / 2;
				rect = new Rectangle(beginPoint, 0, height, height);
			}
		}
		info.setQuality(85);
		MagickImage image = new MagickImage(info);
		image.profileImage("*", null);
		MagickImage cropped = image.cropImage(rect).scaleImage(size, size);
		cropped = cropped.sharpenImage(1.0, 5.0);
		cropped.setFileName(newFileName);
		cropped.writeImage(info);
	}
	public void makeImage(String newFile, byte type, int size) throws Exception {
		if (type == ImageUtil.IMG_SQUARE) {
			this.makeSquare(newFile, size);
		}
		else if (type == ImageUtil.IMG_OBLONG) {
			if (size <= 120) {
				this.makeSmall(newFile, size);
			}
			else if (size > 120) {
				this.makeBig(newFile, size);
			}
		}
	}
	public static Map<String, Object> getImageInfo(Object input) throws Exception {
		ImageInputStream iis = null;
		System.out.println("------------------2--------------------");
		Map<String, Object> map = new HashMap<String, Object>();
		try {
			
			iis = ImageIO.createImageInputStream(input);
			System.out.println("------------------3--------------------");
			Iterator<ImageReader> readers = ImageIO.getImageReaders(iis);
			System.out.println("------------------4--------------------");
			if (readers.hasNext()) {
				ImageReader reader = readers.next();
				reader.setInput(iis);
				String imgType = reader.getFormatName();
				if (imgType.equalsIgnoreCase("JPEG") || (imgType.equalsIgnoreCase("gif")) || imgType.equalsIgnoreCase("png")) {
					int width = reader.getWidth(0);
					int height = reader.getHeight(0);
					map.put("width", width);
					map.put("height", height);
					if (iis != null) {
						iis.close();
						iis = null;
					}
				}
			}
			System.out.println("------------------5--------------------");
			return map;
		}
		catch (IOException e) {
			log.error(e.toString());
			e.printStackTrace();
			throw new Exception(e);
		}
		finally {
			if (iis != null) {
				iis.close();
				iis = null;
			}
		}
	}
	
	/**
	 * 图片上传压缩
	 * @author hanwei (hanwei.1980@hotmail.com)
	 * Create on 2009-4-13 上午10:07:48
	 * @param cid			餐厅id
	 * @param file			上传的图片文件
	 * @param no1_path		小图路径+名称
	 * @param no2_path		中图路径+名称
	 * @param no3_path		大图路径+名称
	 * @param picDefault	默认图片
	 * @param picPath		图片路径
	 * @throws Exception
	 */
	public static void CutPic(int cid, File file, String no1_path,
			String no2_path, String no3_path,String picPath) throws Exception {

		File f = new File(picPath);
		if (!f.exists()) {
			f.mkdirs();
		}
		log.info("============================cmyk2rgb=CutPic begin -=============================");
		//图片属性转换
		cmyk2rgb(no3_path);
		log.info("=============================cmyk2rgb=CutPic end  -=============================");
		Map<String, Object> map = ImageUtil.getImageInfo(file);
		int width = (Integer) map.get("width");
		int heigth = (Integer) map.get("height");
		try{
			log.info("=============================makepic begin -=============================");
			ImageUtil iu = new ImageUtil(width, heigth, file.getAbsolutePath());
			if (width / heigth >= 4 / 3) {
				iu.makePic(no1_path, 120, (heigth * 120) / width);
				iu.makePic(no2_path, 320, (heigth * 320) / width);
			} else {
				iu.makePic(no1_path, (width * 90) / heigth, 90);
				iu.makePic(no2_path, (width * 240) / heigth, 240);
			}
			iu.makePic(no3_path, width, heigth);
			
			log.info("=============================makepic end -=============================");
		}catch(Exception e){
			e.printStackTrace();
		}
	}
	/***
	 * 餐厅上传优惠�?指定尺寸
	 * @param file
	 * @param no1_path
	 * @param picPath
	 * @param needwidth
	 * @param needheight
	 * @param needType
	 * @throws Exception
	 */
   public static void CutPicForYhqLeft(File file,String no1_path,String picPath,int needwidth,int needheight,int needType)throws Exception{
	   File f = new File(picPath);
	   if (!f.exists()) {
			f.mkdirs();
		}
	   Map<String, Object> map = ImageUtil.getImageInfo(file);
	   int width=(Integer) map.get("width");
	   int heigth=(Integer) map.get("height");
	   ImageUtil iu = new ImageUtil(width, heigth, file.getAbsolutePath());
	   if(needType==1){
		if(width/heigth>=5/3) {
			iu.makePic(no1_path, needwidth, (heigth*needwidth)/width);
		}else{
			iu.makePic(no1_path, (width*needheight)/heigth, needheight);
		}
	   }else{
			iu.makePic(no1_path, needwidth, needheight);
	   }
   }
   
   /**
    * 
    * @param clientid
    * @param picname
    * @param tjcId
    */
   public static void CutPicForDefaultTjc(Integer clientid, String picname, Long tjcId) {
		String path = ImageUtil.getPathById(CommonConfig.getParamete("IMAGE_PATH"), clientid,"images");
		String def_name = "tjc_default_" + tjcId + ".jpg";
		picname += "_1.jpg";
		File old_file = new File(path + picname);
		File def_file = new File(path + def_name);
		try {
			log.info("=============================cmyk2rgb  -CutPicForDefaultTjc=============================");
			//图片属性转换
			cmyk2rgb(path + picname);
			log.info("=============================cmyk2rgb  -CutPicForDefaultTjc= end ============================");
			FileUtils.copyFile(old_file, def_file);
		} catch (IOException e) {
			log.error("拷贝特价菜默认图失败", e);
		} catch (Exception e) {
			log.error("拷贝特价菜默认图失败", e);
		}

	}
  
   /**
    * 剪切单张餐厅自传图片
    * @param file
    * @param width_1
    * @param height_1
    * @throws Exception
    */
  public static void CutPicForYhqForlist(File file,int width_1,int height_1)throws Exception{
	   Map<String, Object> map = ImageUtil.getImageInfo(file);
	   int width=(Integer) map.get("width");
	   int heigth=(Integer) map.get("height");
	   cmyk2rgb(file.getAbsolutePath());
	   ImageUtil iu = new ImageUtil(width, heigth, file.getAbsolutePath());
	   iu.makePic(file.getAbsolutePath(), width_1, height_1);
  }
	
	/**
	 * 根据id生成完整路径,并在文件系统中生成这些文件夹
	 * @param prePath
	 * @param id
	 * @return
	 */
	public static String getPathById(String prePath, int id) {
		/**
		 * 根据餐厅id按照3位来分割
		 */
		String strId = Integer.toString(id);
		int iPost = (3 < strId.length()) ? 3 : strId.length();
		int kk = 0;
		StringBuffer sbFileName = new StringBuffer();
		while (iPost <= strId.length()) {
			sbFileName.append(strId.substring(kk, iPost));
			sbFileName.append(File.separatorChar);
			kk = iPost;

			iPost += 3;
			iPost = (iPost < strId.length()) ? iPost : strId.length();
			if (kk == iPost) {
				break;
			}
		}
		String filePath = prePath + sbFileName.toString();
		File file = new File(filePath);
		if (!file.exists()) {
			file.mkdirs();
		}
		return filePath;
	}
	/**
	 * 根据id生成完整路径,并在文件系统中生成这些文件夹
	 * 
	 * @param prePath
	 * @param footPath
	 * @param id
	 * @return
	 */
	public static String getPathById(String prePath, int id,String footPath) {
		/**
		 * 根据餐厅id按照3位来分割
		 */
		String strId = Integer.toString(id);
		int iPost = (3 < strId.length()) ? 3 : strId.length();
		int kk = 0;
		StringBuffer sbFileName = new StringBuffer();
		while (iPost <= strId.length()) {
			sbFileName.append(strId.substring(kk, iPost));
			sbFileName.append(File.separatorChar);
//			sbFileName.append("/");
			kk = iPost;

			iPost += 3;
			iPost = (iPost < strId.length()) ? iPost : strId.length();
			if (kk == iPost) {
				break;
			}
		}
		String filePath = prePath + sbFileName.toString() + footPath + File.separatorChar;
//		String filePath = prePath + sbFileName.toString() + footPath + "/";
		File file = new File(filePath);
		if (!file.exists()) {
			file.mkdirs();
		}
		return filePath;
	}
	
//	/****
//	 * 图片的刷新
//	 * @param
//	 * @return
//	 * @throws IOException 
//	 */ 
//     public static void refreshPic(String  ref_url) throws IOException {   
//				URL  url = new URL(Common.UPDATE_CACHE_URL+ref_url);
//				Object obj = url.getContent();  			
//       } 
//	public static void main(String args[]){
//		try {
//			ImageUtil.refreshPic("http://images1.fantong.com/cate/700040278/default.jpg");
//		} catch (IOException e) {
//			// TODO Auto-generated catch block
//			e.printStackTrace();
//		}
//	}
     
     /****
	 * 图片转换
	 * 调用linux命令
	 * @param file
	 * @return
	 */
	public static boolean cmyk2rgb(String file) {
		try {
			String[] commands = {"/bin/sh",	"-c","/usr/local/ImageMagick/bin/convert -colorspace rgb " + file + " " + file };
			Process process = Runtime.getRuntime().exec(commands);
			process.waitFor();
			System.out.println("=================== run 图片转换cmyk2rgb end  =======================");
			return true;
		} catch (Exception e) {
			e.printStackTrace();
			return false;
		}
	}
	
	
	/**
	 * 图片上传压缩
	 * @param file
	 * @param no1_path
	 * @param picPath
	 * @throws Exception
	 */
	public static void cutOnePic(File file, String no1_path,int width_1,int height_1) throws Exception {

		//图片属性转换
		cmyk2rgb(no1_path);
		Map<String, Object> map = ImageUtil.getImageInfo(file);
		int width = (Integer) map.get("width");
		int heigth = (Integer) map.get("height");
		try{
			ImageUtil iu = new ImageUtil(width, heigth, file.getAbsolutePath());
			iu.makePic(no1_path, width_1, height_1);
		}catch(Exception e){
			e.printStackTrace();
		}
	}
	

	/**
	 * 切图
	 * @param imgPath 源图路径
	 * @param toPath 修改图路径
	 * @param w 宽
	 * @param h 高
	 * @param x X点	
	 * @param y Y点
	 * @throws MagickException
	 */
	public static void cutImg(String imgPath, String toPath, int w, int h, int x, int y) throws MagickException {
		ImageInfo infoS = null;
		MagickImage image = null;
		MagickImage cropped = null;
		Rectangle rect = null;
		try {
			Map<String, Object> map = ImageUtil.getImageInfo(new File(imgPath));
			int img_w = (Integer) map.get("width"); //原图宽
			int img_h = (Integer) map.get("height");//原图高
			
			if (img_w > 400 && img_h >300)  {
				//选中缩放区域的变量
				double zoom_x , zoom_y , zoom_w, zoom_h;
				zoom_x = x;
				zoom_y = y;
				zoom_w = w;
				zoom_h = h;
				
				//按横图方式缩放的还原
				if (img_w /img_h >= 4/3)  {
				    //还原x坐标
					zoom_x = (img_w *  zoom_x) / 400;
				    x = AppUtil.ObjectToInt(Math.round(zoom_x));
					//还原y坐标
				    zoom_y = ( img_h * zoom_y) /  ((img_h *  400) /img_w);
				    y = AppUtil.ObjectToInt(Math.round(zoom_y)) ; 
				    //还原宽
				    zoom_w = (img_w *  zoom_w) / 400;
					w = AppUtil.ObjectToInt(Math.round(zoom_w));
					//还原高
					zoom_h = ( img_h * zoom_h) /  ((img_h *  400) /img_w);
					h =  AppUtil.ObjectToInt(Math.round(zoom_h));
	
				} else {//按竖图方式绽放的还原
				   //还原x坐标
				    x = AppUtil.ObjectToInt(Math.round((( img_w * zoom_x) /  ((img_w * 300) /img_h))));  
					//还原y坐标
				    y =  AppUtil.ObjectToInt(Math.round(((img_h *  zoom_y) / 300)));
				    //还原宽
					w = AppUtil.ObjectToInt(Math.round((( img_w * zoom_w) /  ((img_w * 300) /img_h)))) ; 
					//还原高
					h=  AppUtil.ObjectToInt(Math.round(((img_h *  zoom_h) / 300)));
				}
			}
			
			infoS = new ImageInfo(imgPath);
			image = new MagickImage(infoS);
			rect = new Rectangle(x, y, w,h);
			cropped = image.cropImage(rect);
			cropped.setFileName(toPath);
			cropped.writeImage(infoS);
		} catch (Exception e) {
			e.printStackTrace();
		} finally {
			if (cropped != null) {
				cropped.destroyImages();
			}
		}
	} 
}